
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // JS 实现一个带并发限制的异度调度器 Scheduler，
    // 保证同时运行的任务最多有两个。完善下面代码中的 Scheduler 类，使得以下程序能正确输出。
    class Scheduler {
      // 初始化
      constructor(max){
        this.waitTasks = [] //等待任务
        this.excutingTasks = [] // 正在运行任务
        this.maxExcutingNum = max || 2 //同时运行最大数
      }
      // 添加任务，正在运行任务数小于限制值，直接运行，否则进入等待队列
      add(task) {
        if(this.excutingTasks.length < this.maxExcutingNum){
          this.run(task)
        }else{
          this.waitTasks.push(task)
        }
      }
      // 执行任务
      run(task){
        let index = this.excutingTasks.push(task) - 1 //记录index，用于删除
        task().then(()=>{
          this.excutingTasks.splice(index,1) //移除运行完的任务
          // 检查是否有等待任务
          if(this.waitTasks.length!=0){
            this.run(this.waitTasks.shift())
          }
        })
      }
    }

    const timeout = (time) =>
      new Promise((resolve) => {
        setTimeout(resolve, time);
      });

    const scheduler = new Scheduler();
    const addTask = (time, order) => {
      scheduler.add(() => timeout(time).then(() => console.log(order)));
    };

    addTask(10000, "1");
    addTask(5000, "2");
    addTask(3000, "3");
    addTask(4000, "4");
    // output：2 3 1 4
    // 一开始，1，2两个任务进入队列。
    // 500ms 时，2完成，输出2，任务3入队。
    // 800ms 时，3完成，输出3，任务4入队。
    // 1000ms 时，1完成，输出1。

  </script>
</body>
</html>